package iit.projects.etaxi.view.converters;

import iit.projects.etaxi.util.Constants;
import iit.projects.etaxi.util.JSFUtils;

import javax.faces.application.FacesMessage;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;


public class InputConverter implements Converter, StateHolder {

    private boolean transientValue = false;
    private boolean allowInBetweenSpace;
    private boolean validateSpecial;

    public InputConverter() {
    }

    public Object getAsObject(FacesContext facesContext, 
                              UIComponent uiComponent, String string) {

        if (facesContext == null || uiComponent == null) {
            throw new NullPointerException();
        }

        try {

            if (string == null || string.equals("")) {
                return null;
            }

            if (string.startsWith(" ")) {
                throw new ConverterException(JSFUtils.getMessageFromBundle("common.validation.leadingSpaces", 
                                                                           FacesMessage.SEVERITY_ERROR));
            }
            if (string.endsWith(" ")) {
                if (allowInBetweenSpace) {
                    throw new ConverterException(JSFUtils.getMessageFromBundle("common.validation.endingSpaces", 
                                                                               FacesMessage.SEVERITY_ERROR));
                } else {
                    throw new ConverterException(JSFUtils.getMessageFromBundle("common.validation.inBetweenSpaces", 
                                                                               FacesMessage.SEVERITY_ERROR));
                }
            }
            if (!allowInBetweenSpace && string.contains(" ")) {
                throw new ConverterException(JSFUtils.getMessageFromBundle("common.validation.inBetweenSpaces", 
                                                                           FacesMessage.SEVERITY_ERROR));
            }

            if (validateSpecial) {
                String specialCharacterValidationRegEx = 
                    allowInBetweenSpace ? JSFUtils.getStringFromBundle(Constants.BundleNames.MESSAGES, "common.validation.specialCharacters.allowInBetweenSpace") 
                    		: JSFUtils.getStringFromBundle(Constants.BundleNames.MESSAGES, "common.validation.specialCharacters.notAllowInBetweenSpace");

                if (!string.matches(specialCharacterValidationRegEx)) {
                    throw new ConverterException(JSFUtils.getMessageFromBundle("common.validation.specialCharacters", 
                                                                               FacesMessage.SEVERITY_ERROR));
                }
            }
            return string;
        } catch (ConverterException e) {
            throw e;
        } catch (Exception e) {
            throw new ConverterException(e);
        }
    }

    public String getAsString(FacesContext facesContext, 
                              UIComponent uiComponent, Object object) {

        if (facesContext == null || uiComponent == null) {
            throw new NullPointerException();
        }

        try {
            if (object == null) {
                return "";
            }
            return (String)object;
        } catch (ConverterException e) {
            throw e;
        } catch (Exception e) {
            throw new ConverterException(e);
        }
    }


    public Object saveState(FacesContext facesContext) {
        Object[] values = new Object[2];
        values[0] = allowInBetweenSpace ? Boolean.TRUE : Boolean.FALSE;
        values[1] = validateSpecial ? Boolean.TRUE : Boolean.FALSE;
        return (values);
    }

    public void restoreState(FacesContext facesContext, Object object) {
        Object values[] = (Object[])object;
        allowInBetweenSpace = ((Boolean)values[0]).booleanValue();
        validateSpecial = ((Boolean)values[1]).booleanValue();
    }

    public boolean isTransient() {
        return this.transientValue;
    }

    public void setTransient(boolean transientValue) {
        this.transientValue = transientValue;
    }

    public void setAllowInBetweenSpace(boolean allowInBetweenSpace) {
        this.allowInBetweenSpace = allowInBetweenSpace;
    }

    public boolean isAllowInBetweenSpace() {
        return allowInBetweenSpace;
    }

    public void setValidateSpecial(boolean validateSpecial) {
        this.validateSpecial = validateSpecial;
    }

    public boolean isValidateSpecial() {
        return validateSpecial;
    }
}
